// utils/websocket.ts
import type { WebSocketConfig } from "@/types/websocket";
export class WebSocketClient {
  private socket: WebSocket | null = null;
  private reconnectAttempts = 0;
  private maxReconnectAttempts: number;
  private reconnectInterval: number;
  private messageHandlers: Array<(data: any) => void> = [];
  private errorHandlers: Array<(error: Event) => void> = [];
  private closeHandlers: Array<(event: CloseEvent) => void> = [];

  constructor(private url: string, private options: WebSocketConfig = { url }) {
    if (!url) {
      throw new Error("WebSocket URL is required");
    }
    this.maxReconnectAttempts = options.maxReconnectAttempts || 5;
    this.reconnectInterval = options.reconnectInterval || 5000;
  }

  connect(): void {
    this.socket = new WebSocket(this.url);

    this.socket.onopen = () => {
      console.log("WebSocket connected");
      this.reconnectAttempts = 0;
      this.options.onOpen?.();
    };

    this.socket.onmessage = (event: MessageEvent) => {
      console.log("WebSocket message received:", event.data);

      try {
        if (event.data.startsWith("回复:")) {
          const contentAfterReply = event.data
            .substring("回复：".length)
            .trim();
          const data = JSON.parse(contentAfterReply);
          this.messageHandlers.forEach((handler) => handler(data));
        } else {
          const data = JSON.parse(event.data);
          this.messageHandlers.forEach((handler) => handler(data));
        }
      } catch (e) {
        console.error("Error parsing WebSocket message:", e);
      }
    };

    this.socket.onerror = (error: Event) => {
      console.error("WebSocket error:", error);
      this.errorHandlers.forEach((handler) => handler(error));
    };

    this.socket.onclose = (event: CloseEvent) => {
      console.log("WebSocket closed:", event);
      this.closeHandlers.forEach((handler) => handler(event));
      if (
        !event.wasClean &&
        this.reconnectAttempts < this.maxReconnectAttempts
      ) {
        setTimeout(() => {
          this.reconnectAttempts++;
          console.log(
            `Attempting to reconnect (${this.reconnectAttempts}/${this.maxReconnectAttempts})`
          );
          this.connect();
        }, this.reconnectInterval);
      }
    };
  }

  send(data: any): void {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(JSON.stringify(data));
    } else {
      console.error("WebSocket is not connected");
    }
  }

  close(code: number = 1000, reason?: string): void {
    if (this.socket) {
      this.socket.close(code, reason);
    }
  }

  addMessageHandler(handler: (data: any) => void): void {
    this.messageHandlers.push(handler);
  }

  addErrorHandler(handler: (error: Event) => void): void {
    this.errorHandlers.push(handler);
  }

  addCloseHandler(handler: (event: CloseEvent) => void): void {
    this.closeHandlers.push(handler);
  }
}
